{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Python基础教程（第3版）_笔记"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "菜谱和算法都由原料（对象）和操作说明（语句）组成。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from IPython.core.interactiveshell import InteractiveShell\n",
    "InteractiveShell.ast_node_interactivity = \"all\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "-4"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "-10%3\n",
    "10%3\n",
    "-10//3 # 整除运算，取整是向下取整\n",
    "-10-((-10//3)*3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "8"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pow(2,3)\n",
    "2**3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "32"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "33"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import math #需要引入\n",
    "math.floor(32.9)\n",
    "math.ceil(32.3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "cmath (复数处理模块)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1j"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import cmath\n",
    "cmath.sqrt(-1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "模块\\__future__让Python具备了时光机的部分功能。对于Python当前不支持，但未来将成为标准组成部分的功能，你可从这个模块进行导入。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "强大的海龟绘图法 \n",
    "- from turtle import *\n",
    "- form turtle as t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"let's go!\""
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'\"hello,word!\"'"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"let's go!\"\n",
    "'\"hello,word!\"'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "nihao tiant\n"
     ]
    }
   ],
   "source": [
    "print(\"nihao\",\"tiant\") #此处打印会多一个空格"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "'Hello,\\nworld!'\n",
      "Hello,\n",
      "world!\n",
      "This is a very long string. It continues here.\n",
      "And it's not over yet. \"Hello, \n",
      "world!\"\n",
      "Still here.\n",
      "Hello, world\n"
     ]
    }
   ],
   "source": [
    "print(repr(\"Hello,\\nworld!\"))\n",
    "print(str(\"Hello,\\nworld!\"))\n",
    "print('''This is a very long string. It continues here.\n",
    "And it's not over yet. \"Hello, \\nworld!\"\n",
    "Still here.''')\n",
    "print \\\n",
    "('Hello, world')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'C:\\nowhere'"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "C:\n",
      "owhere\n",
      "C:\\nowhere\n",
      "C:\\nowhere\\\n",
      "'C:\\nowhere'\n"
     ]
    }
   ],
   "source": [
    "path = 'C:\\nowhere'\n",
    "path\n",
    "print(path)\n",
    "\n",
    "path = 'C:\\\\nowhere'\n",
    "print(path)\n",
    "\n",
    "print(r'C:\\nowhere''\\\\')\n",
    "\n",
    "path = 'C:\\nowhere'\n",
    "print(repr(path))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Unicode查询](https://unicode-table.com)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Æ'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'😊'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'This is a cat: 🐈'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'t'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'This is a dog: 🐕'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"\\u00C6\" \n",
    "\"\\U0001F60A\"\n",
    "\"This is a cat: \\N{Cat}\"\n",
    "\"\\u0074\"\n",
    "\"This is a dog: \\N{Dog}\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python提供了两种类似的类型：不可变的bytes和可变的bytearray。如果需要，可直接创建bytes对象（而不是字符串），方法是使用前缀b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "b'Hello, world!'"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b'Hello, world!'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "b'Hello, world!'"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "b'Hello, world!'"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "b'\\xff\\xfe\\x00\\x00H\\x00\\x00\\x00e\\x00\\x00\\x00l\\x00\\x00\\x00l\\x00\\x00\\x00o\\x00\\x00\\x00,\\x00\\x00\\x00 \\x00\\x00\\x00w\\x00\\x00\\x00o\\x00\\x00\\x00r\\x00\\x00\\x00l\\x00\\x00\\x00d\\x00\\x00\\x00!\\x00\\x00\\x00'"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"Hello, world!\".encode(\"ASCII\")\n",
    "\"Hello, world!\".encode(\"UTF-8\")\n",
    "\"Hello, world!\".encode(\"UTF-32\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "b'Hll, wrld!'"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "b'H?ll?, w?rld!'"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "b'H\\\\xe6ll\\\\xe5, w\\\\xf8rld!'"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "b'H&#230;ll&#229;, w&#248;rld!'"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "b'H\\xc3\\xa6ll\\xc3\\xa5, w\\xc3\\xb8rld!'"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'Hællå, wørld!'"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"Hællå, wørld!\".encode(\"ASCII\", \"ignore\")\n",
    "\"Hællå, wørld!\".encode(\"ASCII\", \"replace\")\n",
    "\"Hællå, wørld!\".encode(\"ASCII\", \"backslashreplace\")\n",
    "\"Hællå, wørld!\".encode(\"ASCII\", \"xmlcharrefreplace\")\n",
    "#几乎在所有情况下，都最好使用UTF-8。事实上，它也是默认使用的编码。\n",
    "\"Hællå, wørld!\".encode()\n",
    "str(bytes(\"Hællå, wørld!\", encoding=\"utf-8\"), encoding=\"utf-8\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "bytearray(b'Hullo!')"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = bytearray(b\"Hello!\")\n",
    "x[1] = ord(b\"u\")  #使用ord获取其序数值（ordinal value）\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 本章介绍的新函数\n",
    "```\n",
    "abs(number) 返回指定数的绝对值\n",
    "bytes(string, encoding[, errors]) 对指定的字符串进行编码，并以指定的方式处理错误\n",
    "cmath.sqrt(number) 返回平方根；可用于负数\n",
    "float(object) 将字符串或数字转换为浮点数\n",
    "help([object]) 提供交互式帮助\n",
    "input(prompt) 以字符串的方式获取用户输入\n",
    "int(object) 将字符串或数转换为整数\n",
    "math.ceil(number) 以浮点数的方式返回向上圆整的结果\n",
    "math.floor(number) 以浮点数的方式返回向下圆整的结果\n",
    "math.sqrt(number) 返回平方根；不能用于负数\n",
    "pow(x, y[, z]) 返回x的y次方对z求模的结果\n",
    "print(object, ...) 将提供的实参打印出来，并用空格分隔\n",
    "repr(object) 返回指定值的字符串表示\n",
    "round(number[, ndigits]) 四舍五入为指定的精度，正好为5时舍入到偶数\n",
    "str(object) 将指定的值转换为字符串。用于转换bytes时，可指定编码和错误处理方式\n",
    "\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第2章 列表和元组"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "列表是可以修改的，而元组不可以。\n",
    "Python支持一种数据结构的基本概念，名为容器（container） 。容器基本上就是可包含其他对象的对象两种主要的容器是序列（如列表和元组）和映射（如字典）。\n",
    "在序列中，每个元素都有编号，而在映射中，每个元素都有名称（也叫键）。有一种既不是序列也不是映射的容器，它就是集合（set）\n",
    "列表 []\n",
    "元组 ()\n",
    "字典 {}\n",
    "\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "有几种操作适用于所有序列，包括**索引、 切片、 相加、 相乘和成员资格检查**。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Year: 1988\n",
      "Month (1-12): 8\n",
      "Day (1-31): 21\n",
      "August 21st, 1988\n"
     ]
    }
   ],
   "source": [
    "months = [\n",
    "'January',\n",
    "'February',\n",
    "'March',\n",
    "'April',\n",
    "'May',\n",
    "'June',\n",
    "'July',\n",
    "'August',\n",
    "'September',\n",
    "'October',\n",
    "'November',\n",
    "'December'\n",
    "]\n",
    "# 一个列表，其中包含数1～ 31对应的结尾\n",
    "endings = ['st', 'nd', 'rd'] + 17 * ['th'] \\\n",
    "+ ['st', 'nd', 'rd'] + 7 * ['th'] \\\n",
    "+ ['st']\n",
    "year = input('Year: ')\n",
    "month = input('Month (1-12): ')\n",
    "day = input('Day (1-31): ')\n",
    "month_number = int(month)\n",
    "day_number = int(day)\n",
    "# 别忘了将表示月和日的数减1，这样才能得到正确的索引\n",
    "month_name = months[month_number-1]\n",
    "ordinal = day + endings[day_number-1]\n",
    "print(month_name + ' ' + ordinal + ', ' + year)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'<'"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "' rf\"tp/wwpto.r\"Pto e ie'"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'r'"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'<a href=\"http://www.python.org\">Python web site</a> rf\"tp/wwpto.r\"Pto e ie'"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'<a href=\"http://www.python.org\">Python web site</a><a href=\"http://www.python.org\">Python web site</a><a href=\"http://www.python.org\">Python web site</a>'"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "51"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'y'"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "' '"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tag = '<a href=\"http://www.python.org\">Python web site</a>'\n",
    "#tag= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n",
    "tag[0]\n",
    "tag[2:-4:2] \n",
    "tag[2:-1:2] [1] #步长也可以为负值\n",
    "tag+tag[2:-4:2]\n",
    "tag * 3\n",
    "'w' in tag\n",
    "len(tag)\n",
    "max(tag)\n",
    "min(tag)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "列表方法\n",
    "append\n",
    "clear\n",
    "copy\n",
    "count\n",
    "enxtend\n",
    "index\n",
    "insert\n",
    "pop\n",
    "remove\n",
    "reverse\n",
    "sort\n",
    "\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['h', 'e', 'l', 'o']"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "['h', 'e', 'l', 'o', 4]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "['h', 'e', 'l', 'o']"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "['h', 'e', 'l', 'o', 4, 'h', 'e', 'l', 'o']"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "['h', 'e', 'l', 'o', 4, 'h', 'e', 'l', 'w', 'o']"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "['h', 'e', 'l', 'o', 'h', 'e', 'l', 'w', 'o']"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "['o', 'w', 'l', 'e', 'h', 'o', 'l', 'e', 'h']"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "['e', 'e', 'h', 'h', 'l', 'l', 'o', 'o', 'w']"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "('o', 'w', 'l', 'e', 'h', 'o', 'l', 'e', 'h')"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "('a', 'b', 'c')"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "(1, 2, 3)"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hello = list(\"hello\")\n",
    "del hello[2] #删除元素\n",
    "hello\n",
    "hello2 = hello.copy()\n",
    "hello.append(4)\n",
    "hello\n",
    "hello2\n",
    "hello.count(4)\n",
    "hello.extend(hello2)\n",
    "hello\n",
    "#a = input(\"input keys\")\n",
    "#if a in hello:\n",
    "#    hello.index(a)\n",
    "#    hello.remove(a)\n",
    "#else:\n",
    "#    print(a + \"not in hello\")\n",
    "\n",
    "hello.insert(-1,\"w\")\n",
    "hello\n",
    "hello.pop(4) #返回弹出的值，并修改了值\n",
    "hello\n",
    "hello.reverse()\n",
    "hello\n",
    "#hello.sort() #无返回值的。不要赋值给别人\n",
    "#hello\n",
    "#hello.sort(key = len,reverse=False)\n",
    "#hello\n",
    "hello3 = sorted(hello) \n",
    "hello3\n",
    "tuple(hello) #函数tuple的工作原理与list很像：它将一个序列或元组作为参数，并将其转换为元组\n",
    "tuple('abc')\n",
    "tuple((1, 2, 3))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(42,)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "(42, 42, 42)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#元组：不可修改的序列\n",
    "(42,)\n",
    "3 * (40 + 2,)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "本章介绍的新函数\n",
    "len(seq) 返回序列的长度\n",
    "list(seq) 将序列转换为列表\n",
    "max(args) 返回序列或一组参数中的最大值\n",
    "min(args) 返回序列和一组参数中的最小值\n",
    "reversed(seq) 让你能够反向迭代序列\n",
    "sorted(seq) 返回一个有序列表，其中包含指定序列中的所有元素\n",
    "tuple(seq) 将序列转换为元组\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第三章 使用字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'hello world 12.343. '"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'first, second and third'"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'to be or not to be'"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'π is approximately 3.141592653589793.'"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "\"Euler's constant is roughly 2.718281828459045.\""
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "\"Euler's constant is roughly 2.718281828459045.\""
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "\"{ceci n'est pas une replacement field}\""
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'3 1 4 2'"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "\"π 'π' '\\\\u03c0'\""
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "π 'π' '\\u03c0'\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'The number is 42.00'"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'         3'"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'312345678914456'"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'Bob       '"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'Guido'"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'One googol is 10,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000'"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'11'"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"hello %s %.3f. \" % ('world',12.34344)\n",
    "\"{}, {} and {}\".format(\"first\", \"second\", \"third\")\n",
    "\"{3} {0} {2} {1} {3} {0}\".format(\"be\", \"not\", \"or\", \"to\")\n",
    "\n",
    "from math import pi,e\n",
    "\"{name} is approximately {value}.\".format(value=pi, name=\"π\")\n",
    "\n",
    "f\"Euler's constant is roughly {e}.\" #在Python 3.6中，如果变量与替换字段同名，可简写。\n",
    "\"Euler's constant is roughly {e}.\".format(e=e)\n",
    "\n",
    "\n",
    "#要在最终结果中包含花括号，可在格式字符串中使用两个花括号（即{{或}}）来指定。\n",
    "\"{{ceci n'est pas une replacement field}}\".format() \n",
    "\n",
    "\"{foo} {} {bar} {}\".format(1, 2, bar=4, foo=3)\n",
    "\n",
    "\"{pi!s} {pi!r} {pi!a}\".format(pi=\"π\")\n",
    "print(\"{pi!s} {pi!r} {pi!a}\".format(pi=\"π\")) #（s、 r和a）指定分别使用str、 repr和ascii进行转换。\n",
    "\"The number is {num:.2f}\".format(num=42)\n",
    "\n",
    "\"{num:10}\".format(num=3)\n",
    "\"{num:10}\".format(num=312345678914456)\n",
    "\"{name:10}\".format(name=\"Bob\")\n",
    "\"{:.5}\".format(\"Guido van Rossum\")\n",
    "'One googol is {:,}'.format(10**100)\n",
    "\n",
    "\"{num:b}\".format(num=3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "字符串格式设置\n",
    "```\n",
    "b 将整数表示为二进制数\n",
    "c 将整数解读为Unicode码点\n",
    "d 将整数视为十进制数进行处理，这是整数默认使用的说明符\n",
    "e 使用科学表示法来表示小数（用e来表示指数）\n",
    "E 与e相同，但使用E来表示指数\n",
    "f 将小数表示为定点数\n",
    "F 与f相同，但对于特殊值（nan和inf），使用大写表示\n",
    "g 自动在定点表示法和科学表示法之间做出选择。这是默认用于小数的说明符，但在默认情况下至少有1位小数\n",
    "G 与g相同，但使用大写来表示指数和特殊值\n",
    "n 与g相同，但插入随区域而异的数字分隔符\n",
    "o 将整数表示为八进制数\n",
    "s 保持字符串的格式不变，这是默认用于字符串的说明符\n",
    "x 将整数表示为十六进制数并使用小写字母\n",
    "X 与x相同，但使用大写字母\n",
    "% 将数表示为百分比值（乘以100，按说明符f设置格式，再在后面加上%）\n",
    "\n",
    "数字 宽度度\n",
    ", 每三位加个逗号\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第2天学习  p45-"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from IPython.core.interactiveshell import InteractiveShell\n",
    "InteractiveShell.ast_node_interactivity = \"all\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Bob       '"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"{:10}\".format(\"Bob\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'0000003.14'"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'      3.14'"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from math import pi\n",
    "'{:010.2f}'.format(pi)\n",
    "'{:10.2f}'.format(pi)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'3.14      \\n   3.14   \\n      3.14'"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'3.14      \\n   3.14   \\n      3.14'"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3.14      \n",
      "   3.14   \n",
      "      3.14\n",
      "3.14      \\n   3.14   \\n      3.14\n"
     ]
    }
   ],
   "source": [
    "'{0:<10.2f}\\n{0:^10.2f}\\n{0:>10.2f}'.format(pi)\n",
    "\"{0:<10.2f}\\n{0:^10.2f}\\n{0:>10.2f}\".format(pi)\n",
    "print('{0:<10.2f}\\n{0:^10.2f}\\n{0:>10.2f}'.format(pi))\n",
    "print(r'{0:<10.2f}\\n{0:^10.2f}\\n{0:>10.2f}'.format(pi))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'$$$ WIN BIG $$$'"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"{:$^15}\".format(\" WIN BIG \")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      3.14\n",
      "     -3.14\n"
     ]
    }
   ],
   "source": [
    "print('{0:10.2f}\\n{1:10.2f}'.format(pi, -pi))  #{0:10.2f}  0:表示第一个变量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      3.14\n",
      "-     3.14\n"
     ]
    }
   ],
   "source": [
    "#说明符=，它指定将填充字符放在符号和数字之间。\n",
    "print('{0:10.2f}\\n{1:=10.2f}'.format(pi, -pi)) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3.1\n",
      "-3.1\n",
      "+3.1\n",
      "-3.1\n",
      " 3.1\n",
      "-3.1\n"
     ]
    }
   ],
   "source": [
    "print('{0:-.2}\\n{1:-.2}'.format(pi, -pi)) #默认设置\n",
    "print('{0:+.2}\\n{1:+.2}'.format(pi, -pi))\n",
    "print('{0: .2}\\n{1: .2}'.format(pi, -pi))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'101010'"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'0b101010'"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'0o52'"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'42'"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'42.0000'"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"{:b}\".format(42)\n",
    "\"{:#b}\".format(42)\n",
    "\"{:#o}\".format(42)\n",
    "\"{:g}\".format(42) \n",
    "\"{:#g}\".format(42) #类型g，它保留小数点后面的零"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Please enter width: 35\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'{:25}{:>10}'"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'{:25}{:>10.2f}'"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "===================================\n",
      "Item                          Price\n",
      "-----------------------------------\n",
      "Apples                         0.40\n",
      "Pears                          0.50\n",
      "Cantaloupes                    1.92\n",
      "Dried Apricots (16 oz.)        8.00\n",
      "Prunes (4 lbs.)               12.00\n",
      "===================================\n"
     ]
    }
   ],
   "source": [
    "# Print a formatted price list with a given width\n",
    "\n",
    "width = int(input('Please enter width: '))\n",
    "\n",
    "price_width = 10\n",
    "item_width  = width - price_width\n",
    "\n",
    "header_fmt = '{{:{}}}{{:>{}}}'.format(item_width, price_width)\n",
    "fmt        = '{{:{}}}{{:>{}.2f}}'.format(item_width, price_width)\n",
    "\n",
    "header_fmt\n",
    "fmt\n",
    "\n",
    "print('=' * width)\n",
    "\n",
    "print(header_fmt.format('Item', 'Price'))\n",
    "\n",
    "print('-' * width)\n",
    "\n",
    "print(fmt.format('Apples', 0.4))\n",
    "print(fmt.format('Pears', 0.5))\n",
    "print(fmt.format('Cantaloupes', 1.92))\n",
    "print(fmt.format('Dried Apricots (16 oz.)', 8))\n",
    "print(fmt.format('Prunes (4 lbs.)', 12))\n",
    "\n",
    "print('=' * width)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "23"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(\"Dried Apricots (16 oz.)\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'*****The Middle by Jimmy Eat World*****'"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'     The Middle by Jimmy Eat World     '"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"The Middle by Jimmy Eat World\".center(39, \"*\")\n",
    "\"The Middle by Jimmy Eat World\".center(39)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "15"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "-1"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "title = \"Monty Python's Flying Circus\"\n",
    "title.find('Flying')\n",
    "title.find('Zirquss')\n",
    "\"Zirquss\" in title"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'/usr/bin/env'"
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'1/2/3/4/5'"
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "C:\\usr\\bin\\env\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "('', 'usr', 'bin', 'env')"
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#join是一个非常重要的字符串方法，其作用与split相反，用于合并序列的元素。\n",
    "dirs = '', 'usr', 'bin', 'env'\n",
    "seq = ['1', '2', '3', '4', '5']\n",
    "'/'.join(dirs)\n",
    "'/'.join(seq)\n",
    "print('C:' + '\\\\'.join(dirs))\n",
    "dirs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'trondheim hammer dance'"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'Trondheim Hammer Dance'.lower()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Theez eez a test'"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'This is a test'.replace('is', 'eez')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'internal whitespace is kept'"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "' internal whitespace is kept '.strip()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'thiz iz an inkredible tezt'"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'thizizaninkredibletezt'"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "table = str.maketrans('cs', 'kz')\n",
    "'this is an incredible test'.translate(table)\n",
    "table = str.maketrans('cs', 'kz',\" \")#第一个字符串中的每个字符都替换为第二个字符串中的相应字\n",
    "#符，第三个参数，指定要将哪些字母删除。\n",
    "'this is an incredible test'.translate(table)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "string.capwords(s[, sep]) 使用split根据sep拆分s，将每项的首字母大写，再以空格为分隔符将它们合并起来\n",
    "ascii(obj) 创建指定对象的ASCII表示\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第四章 当索引行不通时"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'age': 42, 'name': 'Gumby'}"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "{'age': 42, 'name': 'Gumby'}"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "items = [('name', 'Gumby'), ('age', 42)]\n",
    "dict(items)\n",
    "\n",
    "dict(name='Gumby', age=42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{42: 'Foobar'}"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d = {}\n",
    "d[42] = 'Foobar'\n",
    "d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Name: Cecil\n",
      "Phone number (p) or address (a)? p\n",
      "Cecil's phone number is 3158.\n"
     ]
    }
   ],
   "source": [
    "# A simple database\n",
    "\n",
    "# A dictionary with person names as keys. Each person is represented as\n",
    "# another dictionary with the keys 'phone' and 'addr' referring to their phone\n",
    "# number and address, respectively.\n",
    "people = {\n",
    "\n",
    "    'Alice': {\n",
    "        'phone': '2341',\n",
    "        'addr': 'Foo drive 23'\n",
    "    },\n",
    "\n",
    "    'Beth': {\n",
    "        'phone': '9102',\n",
    "        'addr': 'Bar street 42'\n",
    "    },\n",
    "\n",
    "    'Cecil': {\n",
    "        'phone': '3158',\n",
    "        'addr': 'Baz avenue 90'\n",
    "    }\n",
    "\n",
    "}\n",
    "\n",
    "# Descriptive labels for the phone number and address. These will be used\n",
    "# when printing the output.\n",
    "labels = {\n",
    "    'phone': 'phone number',\n",
    "    'addr': 'address'\n",
    "}\n",
    "\n",
    "name = input('Name: ')\n",
    "\n",
    "# Are we looking for a phone number or an address?\n",
    "request = input('Phone number (p) or address (a)? ')\n",
    "\n",
    "# Use the correct key:\n",
    "if request == 'p': key = 'phone'\n",
    "if request == 'a': key = 'addr'\n",
    "\n",
    "# Only try to print information if the name is a valid key in\n",
    "# our dictionary:\n",
    "if name in people: print(\"{}'s {} is {}.\".format(name, labels[key], people[name][key]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"Cecil's phone number is 3258.\""
      ]
     },
     "execution_count": 95,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "phonebook ={'Beth': '9102', 'Alice': '2341', 'Cecil': '3258'}\n",
    "\"Cecil's phone number is {Cecil}.\".format_map(phonebook)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<html>\n",
      "<head><title>My Home Page</title></head>\n",
      "<body>\n",
      "<h1>My Home Page</h1>\n",
      "<p>Welcome to my home page!</p>\n",
      "</body>\n"
     ]
    }
   ],
   "source": [
    "template = '''<html>\n",
    "... <head><title>{title}</title></head>\n",
    "... <body>\n",
    "... <h1>{title}</h1>\n",
    "... <p>{text}</p>\n",
    "... </body>'''\n",
    "data = {'title': 'My Home Page', 'text': 'Welcome to my home page!'}\n",
    "print(template.format_map(data))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python基础教程  P59"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'names': ['Alfred', 'Bertrand']}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "{'names': ['d', 'e']}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "{'names': ['Alfred', 'Bertrand']}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "{'names': ['Alfred', 'Bertrand']}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "{'names': ['Alfred', 'Bertrand', 'Clive']}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "{'names': ['Alfred', 'Bertrand', 'Clive']}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "{'names': ['Alfred', 'Bertrand']}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#浅复制 替换值 不会影响副本。而修改里面的值就会影响。\n",
    "#深复制不会影响。\n",
    "from copy import deepcopy\n",
    "d = {}\n",
    "d[\"names\"] = ['Alfred','Bertrand']\n",
    "d\n",
    "c = d.copy()\n",
    "dc  = deepcopy(d)\n",
    "d['names'] = ['d','e']\n",
    "d\n",
    "c\n",
    "dc\n",
    "\n",
    "d[\"names\"] = ['Alfred','Bertrand']\n",
    "c = d.copy()\n",
    "dc  = deepcopy(d)\n",
    "d['names'].append('Clive')\n",
    "d\n",
    "c\n",
    "dc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'age': None, 'name': None}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "{'age': None, 'name': None}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "{'age': '(unknown)', 'name': '(unknown)'}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 方法fromkeys创建一个新字典\n",
    "{}.fromkeys(['name', 'age'])\n",
    "dict.fromkeys(['name', 'age'])\n",
    "dict.fromkeys(['name', 'age'], '(unknown)')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'N/A'"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d = {}\n",
    "#print(d['name'])\n",
    "print(d.get('name'))\n",
    "d.get('name', 'N/A')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_items([('title', 'Python Web Site'), ('url', 'http://www.python.org'), ('spam', 0)])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "[('title', 'Python Web Site'), ('url', 'http://www.python.org'), ('spam', 0)]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "('url', 'http://www.python.org')"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "dict_keys(['title', 'url', 'spam'])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "dict_values(['Python Web Site', 'http://www.python.org', 0])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'Python Web Site'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "('spam', 0)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'http://www.python.org'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'baidu'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "dict_items([('url', 'www.baidu.com'), ('title', 'baidu')])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "{'title': '百度', 'title1': '地图', 'url': 'www.baidu.com'}"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "dict_values(['www.baidu.com', '百度', '地图'])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "dict_values([11, 22])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d = {'title': 'Python Web Site', 'url': 'http://www.python.org', 'spam': 0}\n",
    "d.items()\n",
    "list(d.items())\n",
    "list(d.items())[1]\n",
    "d.keys()\n",
    "d.values()\n",
    "d.pop(\"title\")\n",
    "d.popitem() #高效\n",
    "#地方式逐个删除并处理所有字典项，这可能很有用，因为这样无需先获取键列表。\n",
    "d.setdefault(\"url\",\"n/a\") #如果没有url 先添加再返回。有则返回\n",
    "d[\"url\"]= \"www.baidu.com\"\n",
    "d.setdefault(\"title\",\"baidu\")\n",
    "d.items()\n",
    "\n",
    "x = {'title':\"百度\"}\n",
    "d.update(x)\n",
    "x = {'title1':\"地图\"}\n",
    "d.update(x)\n",
    "d\n",
    "\n",
    "d.values()\n",
    "d1 = {}\n",
    "d1[1]=11\n",
    "d1[2]=22\n",
    "d1.values()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第5章  条件、循环及其他语句"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Age: 42\n",
      "I_wish_to_register_a_complaint\n",
      "Hello,world!\n",
      "123 233 234 3434\n"
     ]
    }
   ],
   "source": [
    "print('Age:', 42) # 这样中间会有个空格\n",
    "print(\"I\", \"wish\", \"to\", \"register\", \"a\", \"complaint\", sep=\"_\")\n",
    "\n",
    "print('Hello,', end='')\n",
    "print('world!')\n",
    "\n",
    "print(\"123\",233,234,3434,)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " 导入及重命名:\n",
    ">- import somemodule\n",
    "- from somemodule import somefunction\n",
    "- from somemodule import somefunction, anotherfunction, yetanotherfunction\n",
    "- from somemodule import *\n",
    "- import math as foobar\n",
    "- from math import sqrt as foobar\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3\n",
      "2 1 3\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(1, 2, 3)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 序列解包（或可迭代对象解包）\n",
    "x, y, z = 1, 2, 3\n",
    "print(x,y,z)\n",
    "x,y = y,x\n",
    "print(x,y,z)\n",
    "\n",
    "values = 1, 2, 3\n",
    "x, y, z = values\n",
    "values\n",
    "x\n",
    "y\n",
    "z"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'girlfriend'"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "scoundrel = {'name': 'Robin', 'girlfriend': 'Marion'}\n",
    "key, value = scoundrel.popitem() # ('girlfriend', 'Marion')\n",
    "key"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[3, 4]"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a, b, *rest = [1, 2, 3, 4]\n",
    "rest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Albus', 'Percival', 'Wulfric', 'Brian', 'Dumbledore']"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'Albus'"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "['Percival', 'Wulfric', 'Brian']"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'Dumbledore'"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "name = \"Albus Percival Wulfric Brian Dumbledore\"\n",
    "name.split(\" \")\n",
    "first, *middle, last = name.split()\n",
    "first\n",
    "middle\n",
    "last"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'a'"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "['b']"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'c'"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a, *b, c= \"abc\"\n",
    "a\n",
    "b\n",
    "c\n",
    "a = c = 2\n",
    "a\n",
    "c\n",
    "a+c"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "各种类型（包括浮点数、复数等）的数值0、空序列（如空字符串、空元组和空列表）以及空映射（如空字典）都被视为假，而其他各种值都被视为真①，"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "43"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "True + False + 42\n",
    "bool('')\n",
    "bool(42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "What is your name?hh\n",
      "Hello, stranger\n"
     ]
    }
   ],
   "source": [
    "name = input('What is your name?')\n",
    "if name.endswith('Gumby'):\n",
    "    print('Hello, Mr. Gumby')\n",
    "else:\n",
    "    print('Hello, stranger')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'stranger'"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# name = \"Gumby\"\n",
    "status = \"friend\" if name.endswith(\"Gumby\") else \"stranger\"\n",
    "status"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "表 达 式 描 述\n",
    "x == y x 等于y\n",
    "x < y x小于y\n",
    "x > y x大于y\n",
    "x >= y x大于或等于y\n",
    "x <= y x小于或等于y\n",
    "x != y x不等于y\n",
    "x is y x和y是同一个对象\n",
    "x is not y x和y是不同的对象\n",
    "x in y x是容器（如序列） y的成员\n",
    "x not in y x不是容器（如序列） y的成员\n",
    "\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x=3\n",
    "y=3\n",
    "x is y\n",
    "x = [1, 2, 3]\n",
    "y = [1, 2, 3]\n",
    "x is y\n",
    "x == y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'🙈'"
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chr(128584)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "ename": "AssertionError",
     "evalue": "The age must be realisitic",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mAssertionError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-27-39e117a2a618>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[0mage\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[1;32massert\u001b[0m \u001b[1;36m0\u001b[0m \u001b[1;33m<\u001b[0m \u001b[0mage\u001b[0m \u001b[1;33m<\u001b[0m \u001b[1;36m100\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;34m\"The age must be realisitic\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mAssertionError\u001b[0m: The age must be realisitic"
     ]
    }
   ],
   "source": [
    "age = -1\n",
    "assert 0 < age < 100,\"The age must be realisitic\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"alpha\" < \"beta\"\n",
    "\"blpha\" >= \"beta\"\n",
    "[2, [1, 4]] < [2, [1, 5]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 循环"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 5, 6, 7, 8, 9]"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(1,10))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "123456789"
     ]
    }
   ],
   "source": [
    "for number in range(1,10):\n",
    "    print(number,end = \"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x corresponds to  1\n",
      "y corresponds to  2\n",
      "z corresponds to  3\n"
     ]
    }
   ],
   "source": [
    "d = {'x': 1, 'y': 2, 'z': 3}\n",
    "for key in d:\n",
    "    print(key, \"corresponds to \", d[key])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x corresponds to 1\n",
      "y corresponds to 2\n",
      "z corresponds to 3\n"
     ]
    }
   ],
   "source": [
    "for key, value in d.items():\n",
    "    print(key, 'corresponds to', value)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[('anne', 12), ('beth', 45), ('george', 32), ('damon', 102)]"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "anne is 12 years old\n",
      "beth is 45 years old\n",
      "george is 32 years old\n",
      "damon is 102 years old\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "names = ['anne', 'beth', 'george', 'damon']\n",
    "ages = [12, 45, 32, 102]\n",
    "list(zip(names, ages)) # 并行迭代工具是内置函数zip，它将两个\n",
    "# 序列“缝合”起来，并返回一个由元组组成的序列。返回值是一个适合迭代的对象，当序列的长度不同时，函数zip将\n",
    "# 在最短的序列用完后停止“缝合”。\n",
    "for name, age in zip(names, ages):\n",
    "    print(name, 'is', age, 'years old')\n",
    "    \n",
    "list(zip(range(5), range(100000000)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "['[censored]', '12']"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "strings = [\"xxx\",\"12\"]\n",
    "# index = 0\n",
    "# for string in strings:\n",
    "#     if 'xxx' in string:\n",
    "#         strings[index] = '[censored]'\n",
    "#         index += 1\n",
    "# index\n",
    "# strings  \n",
    "\n",
    "for index, string in enumerate(strings):\n",
    "    if 'xxx' in string:\n",
    "        strings[index] = '[censored]'\n",
    "index\n",
    "strings\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[3, 3, 4, 6, 8]"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "[3, 8, 6, 3, 4]"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "[3, 8, 6, 3, 4]"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "[3, 3, 4, 6, 8]"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[4, 3, 6, 8, 3]\n",
      "a.sort(): [3, 3, 4, 6, 8]\n",
      "a.reverse(): [8, 6, 4, 3, 3]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'!dlrow ,olleH'"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "' !,deHllloorw'"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "['a', 'B', 'c']"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sorted([4, 3, 6, 8, 3])\n",
    "list(reversed([4, 3, 6, 8, 3])) #反转\n",
    "a= [4, 3, 6, 8, 3]\n",
    "list(reversed(a))\n",
    "sorted(a)\n",
    "print(a)\n",
    "a.sort()\n",
    "print(\"a.sort():\",a)\n",
    "a.reverse()\n",
    "print(\"a.reverse():\",a)\n",
    "''.join(reversed('Hello, world!'))\n",
    "\"\".join(sorted('Hello, world!', key=str.lower))\n",
    "sorted(\"aBc\", key=str.lower)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n"
     ]
    }
   ],
   "source": [
    "from math import sqrt\n",
    "for n in range(3, 0, -1):\n",
    "    root = sqrt(n)\n",
    "    if root == int(root):\n",
    "        print(n)\n",
    "        break\n",
    "else:\n",
    "    print(\"Didn't find it!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]"
      ]
     },
     "execution_count": 118,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]"
      ]
     },
     "execution_count": 118,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[x * x for x in range(10)]\n",
    "[(x, y) for x in range(3) for y in range(3)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['chris+clarice',\n",
       " 'arnold+alice',\n",
       " 'arnold+aa',\n",
       " 'bob+bernice',\n",
       " 'a+alice',\n",
       " 'a+aa']"
      ]
     },
     "execution_count": 129,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "{'a': ['alice', 'aa'], 'b': ['bernice'], 'c': ['clarice']}"
      ]
     },
     "execution_count": 129,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "['chris+clarice',\n",
       " 'arnold+alice',\n",
       " 'arnold+aa',\n",
       " 'bob+bernice',\n",
       " 'a+alice',\n",
       " 'a+aa']"
      ]
     },
     "execution_count": 129,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "girls = ['alice', 'bernice', 'clarice','aa']\n",
    "boys = ['chris', 'arnold', 'bob','a'] #思考下 当增加一个元素如何处理\n",
    "[b+\"+\"+g for b in boys for g in girls if b[0]==g[0]]\n",
    "\n",
    "# 更好的解决办法  \n",
    "letterGirls = {}\n",
    "for girl in girls:\n",
    "    letterGirls.setdefault(girl[0], []).append(girl)\n",
    "letterGirls\n",
    "# letterGirls['a']\n",
    "[b+'+'+g for b in boys for g in letterGirls[b[0]]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0: '0 squared is 0',\n",
       " 1: '1 squared is 1',\n",
       " 2: '2 squared is 4',\n",
       " 3: '3 squared is 9',\n",
       " 4: '4 squared is 16',\n",
       " 5: '5 squared is 25',\n",
       " 6: '6 squared is 36',\n",
       " 7: '7 squared is 49',\n",
       " 8: '8 squared is 64',\n",
       " 9: '9 squared is 81'}"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'9 squared is 81'"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "squares = {i:\"{} squared is {}\".format(i, i**2)  for i in range(10)}\n",
    "squares\n",
    "squares.get(9)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " - pass\n",
    " - del \n",
    " - exec"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 146,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 146,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "2.0"
      ]
     },
     "execution_count": 146,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 146,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "dict_keys(['__builtins__', 'sqrt'])"
      ]
     },
     "execution_count": 146,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from math import sqrt\n",
    "exec(\"sqrt = 1\")\n",
    "sqrt \n",
    "\n",
    "from math import sqrt\n",
    "scope = {}\n",
    "exec('sqrt = 1', scope)\n",
    "sqrt(4)\n",
    "scope['sqrt']\n",
    "scope.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 149,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Enter an arithmetic expression: 12+23\n"
     ]
    }
   ],
   "source": [
    "exec(input(\"Enter an arithmetic expression: \"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Enter an arithmetic expression: 12+32\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "44"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "eval(input(\"Enter an arithmetic expression: \"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "本章介绍的新函数\n",
    "chr(n) 返回一个字符串，其中只包含一个字符，这个字符对应于传入的顺序值n（0 ≤n < 256）\n",
    "eval(source[,globals[,locals]]) 计算并返回字符串表示的表达式的结果\n",
    "exec(source[, globals[, locals]]) 将字符串作为语句执行\n",
    "enumerate(seq) 生成可迭代的索引值对\n",
    "ord(c) 接受一个只包含一个字符的字符串，并返回这个字符的顺序值（一个整数）\n",
    "range([start,] stop[, step]) 创建一个由整数组成的列表\n",
    "reversed(seq) 按相反的顺序返回seq中的值，以便用于迭代\n",
    "sorted(seq[,cmp][,key][,reverse]) 返回一个列表，其中包含seq中的所有值且这些值是经过排序的\n",
    "xrange([start,] stop[, step]) 创建一个用于迭代的xrange对象\n",
    "zip(seq1, seq2,...) 创建一个适合用于并行迭代的新序列\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第6章 抽象"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "要判断某个对象是否可调用，可使用内置函数callable。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 152,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 152,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 152,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import math\n",
    "x =1\n",
    "y = math.sqrt\n",
    "callable(x)\n",
    "callable(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Mr. Gumby', 'Mrs. Thing']"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "names = ['Mrs. Entity', 'Mrs. Thing']\n",
    "n = names # 再次假装传递名字作为参数\n",
    "n[0] = 'Mr. Gumby' # 修改列表\n",
    "names\n",
    "names = ['Mrs. Entity', 'Mrs. Thing']\n",
    "n = names[:]\n",
    "n is names\n",
    "n == names"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def square(x):\n",
    "    'Calculates the square of the number x.'\n",
    "?square"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'x': 1, 'y': 2, 'z': 3}\n"
     ]
    }
   ],
   "source": [
    "def print_params_3(**params):\n",
    "    print(params)\n",
    "    \n",
    "print_params_3(x=1, y=2, z=3)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3\n",
      "[(5, 6, 7), 1]\n",
      "{'foo': 1, 'bar': 2}\n",
      "Object `pospar` not found.\n"
     ]
    }
   ],
   "source": [
    "def print_params_4(x, y, z=3, *pospar, **keypar):\n",
    "    print(x, y, z)\n",
    "    print([pospar,x])\n",
    "    print(keypar)\n",
    "    \n",
    "    \n",
    "print_params_4(1, 2, 3, 5, 6, 7, foo=1, bar=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "本章介绍的新函数\n",
    "map(func, seq[, seq, ...]) 对序列中的所有元素执行函数\n",
    "filter(func, seq) 返回一个列表，其中包含对其执行函数时结果为真的所有元素\n",
    "reduce(func, seq[, initial]) 等价于 func(func(func(seq[0], seq[1]), seq[2]), ...)\n",
    "sum(seq) 返回 seq 中所有元素的和\n",
    "apply(func[, args[, kwargs]]) 调用函数（还提供要传递给函数的参数）\n",
    "\n",
    "\n",
    "\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第7章  再谈抽象"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "多态， 封装， 继承，类 。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#多态\n",
    "# 例如 count 无论是字符串或者列表都可以用\n",
    "\"abc\".count(\"a\")\n",
    "[1,2,\"a\"].count(\"a\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from random import choice\n",
    "x = choice(['Hello, world!', [1, 2, 'e', 'e', 4]])\n",
    "x.count('e')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "类.类里面的函数是方法。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello, world! I'm keven.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'keven'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I don't...\n"
     ]
    }
   ],
   "source": [
    "__metaclass__ = type # 如果你使用的是Python 2，请包含这行代码\n",
    "class Person:\n",
    "    def set_name(self, name):#方法\n",
    "        self.name = name\n",
    "    def get_name(self):\n",
    "        return self.name\n",
    "    def greet(self):\n",
    "        print(\"Hello, world! I'm {}.\".format(self.name))\n",
    "        \n",
    "def function():# 函数\n",
    "    print(\"I don't...\")\n",
    "#如果foo是一个Person实例，可将foo.greet()视为Person.greet(foo)的简写，\n",
    "# 但后者的多态性更低。        \n",
    "foo = Person()\n",
    "foo.set_name(name =\"keven\")\n",
    "foo.greet()\n",
    "foo.name\n",
    "\n",
    "foo.name= function()\n",
    "foo.name"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "要让方法或属性成为私有的（不能从外部访问），只需让其名称以两个下划线打头即可。from module import *不会导入以一个下划线打头的名称"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Bet you can't see me ...\n",
      "The secret message is:\n",
      "Bet you can't see me ...\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "__main__.Secretive"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class Secretive:\n",
    "    def __inaccessible(self):\n",
    "        print(\"Bet you can't see me ...\")\n",
    "    def accessible(self):\n",
    "        print(\"The secret message is:\")\n",
    "        self.__inaccessible()\n",
    "        \n",
    "s = Secretive()\n",
    "s._Secretive__inaccessible()  #不推荐这样用\n",
    "s.accessible()\n",
    "Secretive"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "16"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "16"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "<function __main__.<lambda>>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def foo(x): return x * x\n",
    "foo3 = lambda x: x * x\n",
    "\n",
    "foo(4)\n",
    "foo3(4)\n",
    "foo3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'Two'"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class MemberCounter:\n",
    "    members = 0\n",
    "    def init(self):\n",
    "        MemberCounter.members += 1\n",
    "        \n",
    "m1 = MemberCounter()\n",
    "m1.init()\n",
    "MemberCounter.members\n",
    "m1.members\n",
    "\n",
    "m2 = MemberCounter()\n",
    "m2.init()\n",
    "MemberCounter.members\n",
    "m2.members\n",
    "\n",
    "m1.members = 'Two'  #新值被写入m1的一个属性中，这个属性对于m1遮住了类级变量。\n",
    "m1.members\n",
    "\n",
    "m2.members\n",
    "MemberCounter.members"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 超类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3]"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "['eggs', 'bacon']"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "(__main__.Filter,)"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "__main__.SPAMFilter"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class Filter:\n",
    "    def init(self):\n",
    "        self.blocked = []\n",
    "    def filter(self, sequence):\n",
    "        return [x for x in sequence if x not in self.blocked]\n",
    "class SPAMFilter(Filter): # SPAMFilter是Filter的子类\n",
    "    def init(self): # 重写超类Filter的方法init\n",
    "        self.blocked = ['SPAM']\n",
    "        \n",
    "f = Filter()\n",
    "f.init()\n",
    "f.filter([1, 2, 3])\n",
    "\n",
    "s = SPAMFilter()\n",
    "s.init()\n",
    "s.filter(['SPAM', 'SPAM', 'SPAM', 'SPAM', 'eggs', 'bacon', 'SPAM'])\n",
    "\n",
    "# 要确定一个类是否是另一个类的子类issubclass\n",
    "issubclass(SPAMFilter , Filter)\n",
    "SPAMFilter.__bases__\n",
    "\n",
    "isinstance(s, SPAMFilter)\n",
    "isinstance(s, Filter)\n",
    "isinstance(s, str)\n",
    "s.__class__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hi, my value is 7\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'Mr. Gumby'"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "{'name': 'Mr. Gumby', 'value': 7}"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#多重继承. \n",
    "# 注意：多个超类的超类相同时，前面的超类的方法可以使用，\n",
    "# 查找特定方法或属性时访问超类的顺序称为方法解析顺序（MRO），\n",
    "class Calculator:\n",
    "    def calculate(self, expression):\n",
    "        self.value = eval(expression)\n",
    "class Talker:\n",
    "    def talk(self):\n",
    "        print('Hi, my value is', self.value)\n",
    "class TalkingCalculator(Calculator, Talker):\n",
    "    pass\n",
    "\n",
    "\n",
    "tc = TalkingCalculator()\n",
    "tc.calculate('1 + 2 * 3')\n",
    "tc.talk()\n",
    "\n",
    "hasattr(tc, 'talk') #检查所需的方法是否存在；\n",
    "callable(getattr(tc, 'talk', None)) #检查属性talk是否是可调用的。\n",
    "\n",
    "setattr(tc, 'name', 'Mr. Gumby')\n",
    "tc.name\n",
    "tc.__dict__\n",
    "# __dict__    inspect "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "抽象类是不能（至少是不应该）实例化的类，其职责是定义子类应实现的一组抽象方法。\n",
    "在历史上的大部分时间内， Python几乎都只依赖\n",
    "于鸭子类型，即假设所有对象都能完成其工作，同时偶尔使用hasattr来检查所需的方法是否存\n",
    "在。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "__main__.Herring"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Blub.\n"
     ]
    }
   ],
   "source": [
    "from abc import ABC, abstractmethod\n",
    "class Talker(ABC):\n",
    "    @abstractmethod   #使用@abstractmethod来将方法标记为抽象的——在子类中必须实现的方法。\n",
    "    def talk(self):\n",
    "        pass\n",
    "    def talk1(self):\n",
    "        print(\"come\")\n",
    "    \n",
    "class Herring:\n",
    "    def talk(self):\n",
    "        print(\"Blub.\")\n",
    "        \n",
    "h = Herring()\n",
    "isinstance(h,Talker)\n",
    "\n",
    "#将Herring注册为Talker（而不从Herring和Talker派生出子类,无法使用Talker中的方法）\n",
    "Talker.register(Herring)  \n",
    "isinstance(h,Talker)\n",
    "issubclass(Herring, Talker)\n",
    "h.talk()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "register 这种做法存在一个缺点，就是直接从抽象类派生提供的保障没有了。应将isinstance返回True视为一种意图表达。在这里， Clam有成为Talker的意图。\n",
    "本着鸭子类型的精神，我们相信它能承担Talker的职责，但可悲的是它失败了。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "本章介绍的新函数\n",
    "callable(object) 判断对象是否是可调用的（如是否是函数或方法）\n",
    "getattr(object,name[,default]) 获取属性的值，还可提供默认值\n",
    "hasattr(object, name) 确定对象是否有指定的属性\n",
    "isinstance(object, class) 确定对象是否是指定类的实例\n",
    "issubclass(A, B) 确定A是否是B的子类\n",
    "random.choice(sequence) 从一个非空序列中随机地选择一个元素\n",
    "setattr(object, name, value) 将对象的指定属性设置为指定的值\n",
    "type(object) 返回对象的类型\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第八章 异常"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "ename": "ZeroDivisionError",
     "evalue": "division by zero",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mZeroDivisionError\u001b[0m                         Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-26-16f0c2652a89>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m     13\u001b[0m \u001b[0mcalculator\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mMuffledCalculator\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     14\u001b[0m \u001b[0mcalculator\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmuffled\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mFalse\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 15\u001b[1;33m \u001b[0mcalculator\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcalc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'10 / 0'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     16\u001b[0m \u001b[1;31m# calculator.muffled = True\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     17\u001b[0m \u001b[1;31m# calculator.calc('10 / 0')\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m<ipython-input-26-16f0c2652a89>\u001b[0m in \u001b[0;36mcalc\u001b[1;34m(self, expr)\u001b[0m\n\u001b[0;32m      3\u001b[0m     \u001b[1;32mdef\u001b[0m \u001b[0mcalc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mexpr\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      4\u001b[0m         \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m             \u001b[1;32mreturn\u001b[0m \u001b[0meval\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mexpr\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      6\u001b[0m         \u001b[1;32mexcept\u001b[0m \u001b[0mZeroDivisionError\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      7\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmuffled\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m<string>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n",
      "\u001b[1;31mZeroDivisionError\u001b[0m: division by zero"
     ]
    }
   ],
   "source": [
    "class MuffledCalculator:\n",
    "    muffled = False\n",
    "    def calc(self, expr):\n",
    "        try:\n",
    "            return eval(expr)\n",
    "        except ZeroDivisionError:\n",
    "            if self.muffled:\n",
    "                print('Division by zero is illegal')\n",
    "            else:\n",
    "                raise  #无法处理异常 常常不带参数。如果还引发别的异常 带参数。 raise ValueError {from None}\n",
    "                \n",
    "                \n",
    "calculator = MuffledCalculator()\n",
    "calculator.muffled = False\n",
    "calculator.calc('10 / 0')\n",
    "# calculator.muffled = True\n",
    "# calculator.calc('10 / 0')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "try:\n",
    "    x = int(input('Enter the first number: '))\n",
    "    y = int(input('Enter the second number: '))\n",
    "    print(x / y)\n",
    "except (ZeroDivisionError):\n",
    "    print('Your numbers were bogus ...')\n",
    "except ( TypeError, NameError) as e:\n",
    "    print(e)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Enter the first number: 4\n",
      "Enter the second number: 0\n",
      "Your numbers were bogus ...\n",
      "Enter the first number: a\n",
      "Invalid input,Please try again! invalid literal for int() with base 10: 'a'\n",
      "Enter the first number: 3\n",
      "Enter the second number: a\n",
      "Invalid input,Please try again! invalid literal for int() with base 10: 'a'\n",
      "Enter the first number: 4\n",
      "Enter the second number: 5\n",
      "x / y is 0.8\n"
     ]
    }
   ],
   "source": [
    "while True:\n",
    "    try:\n",
    "        x = int(input('Enter the first number: '))\n",
    "        y = int(input('Enter the second number: '))\n",
    "        value = x / y\n",
    "        print('x / y is', value)\n",
    "    except (ZeroDivisionError):\n",
    "        print('Your numbers were bogus ...')\n",
    "    except ( TypeError, NameError) as e:\n",
    "        print(e)\n",
    "    except Exception  as e:\n",
    "        print('Invalid input,Please try again!',e)\n",
    "#         print('Please try again')\n",
    "    else:\n",
    "        break\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Cleaning up.\n"
     ]
    },
    {
     "ename": "ZeroDivisionError",
     "evalue": "division by zero",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mZeroDivisionError\u001b[0m                         Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-2-9f439a05c13c>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m     \u001b[1;36m1\u001b[0m \u001b[1;33m/\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      3\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mNameError\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      4\u001b[0m     \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Unknown variable\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      5\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mZeroDivisionError\u001b[0m: division by zero"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    1 / 0\n",
    "except NameError:\n",
    "    print(\"Unknown variable\")\n",
    "else:\n",
    "    print(\"That went well!\")\n",
    "finally:\n",
    "    print(\"Cleaning up.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "ename": "DeprecationWarning",
     "evalue": "This function is really old...",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mDeprecationWarning\u001b[0m                        Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-34-da9914f2bb6e>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      5\u001b[0m \u001b[0mfilterwarnings\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"error\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      6\u001b[0m \u001b[1;31m# warn(\"Something is very wrong!\")\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 7\u001b[1;33m \u001b[0mwarn\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"This function is really old...\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mDeprecationWarning\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mDeprecationWarning\u001b[0m: This function is really old..."
     ]
    }
   ],
   "source": [
    "from warnings import warn\n",
    "from warnings import filterwarnings\n",
    "filterwarnings(\"ignore\")\n",
    "warn(\"Anyone out there?\")\n",
    "filterwarnings(\"error\")\n",
    "# warn(\"Something is very wrong!\")\n",
    "warn(\"This function is really old...\", DeprecationWarning)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "本章介绍的新函数\n",
    "warnings.filterwarnings(action,category=Warning, ...) 用于过滤警告\n",
    "warnings.warn(message, category=None) 用于发出警告\n",
    "raise\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第九章 魔法方法、特性和迭代器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "构造函数 \\__init__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Squawk!\n",
      "Aaaah ...\n",
      "No, thanks!\n"
     ]
    }
   ],
   "source": [
    "class Bird:\n",
    "    def __init__(self):\n",
    "        self.hungry = True\n",
    "    def eat(self):\n",
    "        if self.hungry:\n",
    "            print('Aaaah ...')\n",
    "            self.hungry = False\n",
    "        else:\n",
    "            print('No, thanks!')\n",
    "            \n",
    "class SongBird(Bird):\n",
    "    def __init__(self):\n",
    "#         Bird.__init__(self)\n",
    "        super().__init__()#即便有多个超类\n",
    "        self.sound = 'Squawk!'\n",
    "    def sing(self):\n",
    "        print(self.sound)\n",
    "        \n",
    "sb = SongBird()\n",
    "sb.sing()\n",
    "sb.eat()\n",
    "sb.eat()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 基本序列和映射协议。\n",
    "```序列和映射基本上是元素（item）的集合，要实现它们的基本行为（协议） ，不可变对象需要实现2个方法，而可变对象需要实现4个。 __len__(self)；\n",
    "__getitem__(self, key) ; __setitem__(self, key, value)； __delitem__(self, key)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def check_index(key):\n",
    "    \"\"\"\n",
    "    指定的键是否是可接受的索引？\n",
    "    键必须是非负整数，才是可接受的。如果不是整数，\n",
    "    将引发TypeError异常；如果是负数，将引发Index\n",
    "    Error异常（因为这个序列的长度是无穷的）\n",
    "    \"\"\"\n",
    "    if not isinstance(key, int): raise TypeError\n",
    "    if key < 0: raise IndexError\n",
    "\n",
    "?check_index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "[9, 8, 7, 3, 2, 1, 0]"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "9"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\n",
    "class CounterList(list):\n",
    "    def __init__(self, *args):\n",
    "        super().__init__(*args)\n",
    "        self.counter = 0\n",
    "    def __getitem__(self, index):\n",
    "        self.counter += 1\n",
    "        return super(CounterList, self).__getitem__(index)\n",
    "    \n",
    "cl = CounterList(range(10))\n",
    "cl\n",
    "cl.reverse()\n",
    "del cl[3:6]\n",
    "cl\n",
    "cl.counter\n",
    "cl[4] +cl[2]\n",
    "cl.counter"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "特性，函数property"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0, 0)"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "(10, 5)"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "(150, 100)"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "(150, 100)"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class Rectangle:\n",
    "    def __init__ (self):\n",
    "        self.width = 0\n",
    "        self.height = 0\n",
    "    def set_size(self, size):\n",
    "        self.width, self.height = size\n",
    "    def get_size(self):\n",
    "        return self.width, self.height\n",
    "    size = property(get_size, set_size)\n",
    "    \n",
    "r = Rectangle()\n",
    "r.size\n",
    "r.width,r.height = 10,5\n",
    "r.size\n",
    "r.size = 150, 100\n",
    "r.size\n",
    "r.get_size()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "This is a static method\n",
      "This is a class method of <class '__main__.MyClass'>\n"
     ]
    }
   ],
   "source": [
    "class MyClass:\n",
    "    @staticmethod\n",
    "    def smeth():\n",
    "        print('This is a static method')\n",
    "    @classmethod\n",
    "    def cmeth(cls):\n",
    "        print('This is a class method of', cls)\n",
    "        \n",
    "MyClass.smeth()\n",
    "MyClass.cmeth()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " ```\n",
    " __getattribute__(self, name) ; __getattr__(self, name); __setattr__(self, name, value); __delattr__(self, name)：\n",
    " \n",
    " __getattribute__(self, name)：在属性被访问时自动调用（只适用于新式类）。\n",
    " __getattr__(self, name)：在属性被访问而对象没有这样的属性时自动调用。\n",
    " __setattr__(self, name, value)：试图给属性赋值时自动调用。\n",
    " __delattr__(self, name)：试图删除属性时自动调用。\n",
    " \n",
    " \n",
    " \n",
    " ```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "迭代器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class Fibs:\n",
    "    def __init__(self):\n",
    "        self.a = 0\n",
    "        self.b = 1\n",
    "    def __next__(self):\n",
    "        self.a, self.b = self.b, self.a + self.b\n",
    "        if self.a > 100: raise StopIteration \n",
    "        return self.a\n",
    "    def __iter__(self):\n",
    "        return self\n",
    "\n",
    "fibs = Fibs()\n",
    "list(fibs)\n",
    "# for f in fibs:\n",
    "#     if f > 1000:\n",
    "#         print(f)\n",
    "#         break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1597\n"
     ]
    }
   ],
   "source": [
    "class Fibs:\n",
    "    def __init__(self):\n",
    "        self.a = 0\n",
    "        self.b = 1\n",
    "    def __next__(self):\n",
    "        self.a, self.b = self.b, self.a + self.b\n",
    "        #if self.a > 100: raise StopIteration \n",
    "        return self.a\n",
    "    def __iter__(self):\n",
    "        return self\n",
    "\n",
    "fibs = Fibs()\n",
    "\n",
    "for f in fibs:\n",
    "    if f > 1000:\n",
    "        print(f)\n",
    "        break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "4\n",
      "5\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 4, 5]"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 创建生成器\n",
    "def flatten(nested):\n",
    "    try:\n",
    "        for sublist in nested:\n",
    "            for element in sublist:\n",
    "                yield element\n",
    "    except TypeError:\n",
    "        yield nested\n",
    "        \n",
    "nested = [[1, 2], [3, 4,4], [5]]\n",
    "for num in flatten(nested):\n",
    "    print(num)\n",
    "    \n",
    "list(flatten(nested))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用生成器解决八皇后问题：P165"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "本章介绍的新函数\n",
    "iter(obj) 从可迭代对象创建一个迭代器\n",
    "next(it) 让迭代器前进一步并返回下一个元素\n",
    "property(fget, fset, fdel, doc) 返回一个特性；所有参数都是可选的\n",
    "super(class, obj) 返回一个超类的关联实例\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## 第十章 开箱即用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['',\n",
      " 'D:\\\\Applications\\\\Anaconda3\\\\python36.zip',\n",
      " 'D:\\\\Applications\\\\Anaconda3\\\\DLLs',\n",
      " 'D:\\\\Applications\\\\Anaconda3\\\\lib',\n",
      " 'D:\\\\Applications\\\\Anaconda3',\n",
      " 'D:\\\\Applications\\\\Anaconda3\\\\lib\\\\site-packages',\n",
      " 'D:\\\\Applications\\\\Anaconda3\\\\lib\\\\site-packages\\\\Sphinx-1.5.6-py3.6.egg',\n",
      " 'D:\\\\Applications\\\\Anaconda3\\\\lib\\\\site-packages\\\\win32',\n",
      " 'D:\\\\Applications\\\\Anaconda3\\\\lib\\\\site-packages\\\\win32\\\\lib',\n",
      " 'D:\\\\Applications\\\\Anaconda3\\\\lib\\\\site-packages\\\\Pythonwin',\n",
      " 'D:\\\\Applications\\\\Anaconda3\\\\lib\\\\site-packages\\\\setuptools-27.2.0-py3.6.egg',\n",
      " 'D:\\\\Applications\\\\Anaconda3\\\\lib\\\\site-packages\\\\IPython\\\\extensions',\n",
      " 'C:\\\\Users\\\\keven\\\\.ipython']\n"
     ]
    }
   ],
   "source": [
    "import sys, pprint\n",
    "pprint.pprint(sys.path) #搜索路径"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "探索模块"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Error',\n",
       " '__all__',\n",
       " '__builtins__',\n",
       " '__cached__',\n",
       " '__doc__',\n",
       " '__file__',\n",
       " '__loader__',\n",
       " '__name__',\n",
       " '__package__',\n",
       " '__spec__',\n",
       " '_copy_dispatch',\n",
       " '_copy_immutable',\n",
       " '_deepcopy_atomic',\n",
       " '_deepcopy_dict',\n",
       " '_deepcopy_dispatch',\n",
       " '_deepcopy_list',\n",
       " '_deepcopy_method',\n",
       " '_deepcopy_tuple',\n",
       " '_keep_alive',\n",
       " '_reconstruct',\n",
       " 'copy',\n",
       " 'deepcopy',\n",
       " 'dispatch_table',\n",
       " 'error']"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "['Error', 'copy', 'deepcopy']"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function copy in module copy:\n",
      "\n",
      "copy(x)\n",
      "    Shallow copy operation on arbitrary Python objects.\n",
      "    \n",
      "    See the module's __doc__ string for more info.\n",
      "\n",
      "Shallow copy operation on arbitrary Python objects.\n",
      "\n",
      "    See the module's __doc__ string for more info.\n",
      "    \n",
      "D:\\Applications\\Anaconda3\\lib\\copy.py\n"
     ]
    }
   ],
   "source": [
    "import copy\n",
    "dir(copy) #列出对象的所有属性\n",
    "copy.__all__\n",
    "help(copy.copy)\n",
    "print(copy.copy.__doc__)\n",
    "print(copy.__file__)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 标准库\n",
    ">- sys\n",
    "```\n",
    "argv 命令行参数，包括脚本名\n",
    "exit([arg]) 退出当前程序，可通过可选参数指定返回值或错误消息\n",
    "modules 一个字典，将模块名映射到加载的模块\n",
    "path 一个列表，包含要在其中查找模块的目录的名称\n",
    "platform 一个平台标识符，如sunos5或win32\n",
    "stdin 标准输入流——一个类似于文件的对象\n",
    "stdout 标准输出流——一个类似于文件的对象\n",
    "stderr 标准错误流——一个类似于文件的对象.\n",
    "```\n",
    "- os\n",
    "```\n",
    "environ 包含环境变量的映射\n",
    "system(command) 在子shell中执行操作系统命令\n",
    "sep 路径中使用的分隔符\n",
    "pathsep 分隔不同路径的分隔符\n",
    "linesep 行分隔符（'\\n'、 '\\r'或'\\r\\n'）\n",
    "urandom(n) 返回n个字节的强加密随机数据\n",
    "```\n",
    "- fileinput\n",
    "```\n",
    "input([files[, inplace[, backup]]]) 帮助迭代多个输入流中的行\n",
    "filename() 返回当前文件的名称\n",
    "lineno() 返回（累计的）当前行号\n",
    "filelineno() 返回在当前文件中的行号\n",
    "isfirstline() 检查当前行是否是文件中的第一行\n",
    "isstdin() 检查最后一行是否来自sys.stdin\n",
    "nextfile() 关闭当前文件并移到下一个文件\n",
    "close() 关闭序列```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import os\n",
    "os.system(\"cmd\")\n",
    "# os.system(r'D:\\\"Program Files\"\\\"Mozilla Firefox\"\\firefox.exe')\n",
    "# os.startfile(r'D:\\Program Files\\Mozilla Firefox\\firefox.exe')\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import webbrowser\n",
    "webbrowser.open('http://www.python.org')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tiantain                                           # 200\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "55"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "line = \"tiantain\"\n",
    "num = 200\n",
    "print('{:<50} # {:2d}'.format(line, num))  # https://docs.python.org/3.6/library/string.html#formatspec\n",
    "len(\"tiantain                                           # 20\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "set(range(10))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 堆\n",
    "\n",
    "> ```\n",
    "heappush(heap, x) 将x压入堆中\n",
    "heappop(heap) 从堆中弹出最小的元素\n",
    "heapify(heap) 让列表具备堆特征\n",
    "heapreplace(heap, x) 弹出最小的元素，并将x压入堆中\n",
    "nlargest(n, iter) 返回iter中n个最大的元素\n",
    "nsmallest(n, iter) 返回iter中n个最小的元素\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "deque([6, 0, 1, 2, 3, 4, 5])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "6"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "deque([0, 1, 2, 3, 4])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "deque([2, 3, 4, 0, 1])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "deque([3, 4, 0, 1, 2])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from collections import deque\n",
    "q = deque(range(5))\n",
    "q.append(5)\n",
    "q.appendleft(6)\n",
    "q\n",
    "q.pop()\n",
    "q.popleft()\n",
    "q\n",
    "q.rotate(3)\n",
    "q\n",
    "q.rotate(-1)\n",
    "q"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "p190   time\n",
    "```\n",
    "asctime([tuple]) 将时间元组转换为字符串\n",
    "localtime([secs]) 将秒数转换为表示当地时间的日期元组\n",
    "mktime(tuple) 将时间元组转换为当地时间\n",
    "sleep(secs) 休眠（什么都不做） secs秒\n",
    "strptime(string[, format]) 将字符串转换为时间元组\n",
    "time() 当前时间（从新纪元开始后的秒数，以UTC为准）\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Fri Mar 16 10:45:21 2018'"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "1521168321.271651"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import time\n",
    "# dir(time)\n",
    "# time.__package__\n",
    "time.asctime()\n",
    "time.time()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "random\n",
    "```\n",
    "random() 返回一个0~1（含）的随机实数\n",
    "getrandbits(n) 以长整数方式返回n个随机的二进制位\n",
    "uniform(a, b) 返回一个a~b（含）的随机实数\n",
    "randrange([start], stop, [step]) 从range(start, stop, step)中随机地选择一个数\n",
    "choice(seq) 从序列seq中随机地选择一个元素\n",
    "shuffle(seq[, random]) 就地打乱序列seq\n",
    "sample(seq, n) 从序列seq中随机地选择n个值不同的元素\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['6 of diamonds',\n",
      " '4 of diamonds',\n",
      " '3 of spades',\n",
      " 'Jack of spades',\n",
      " '9 of diamonds',\n",
      " '4 of spades',\n",
      " '5 of diamonds',\n",
      " '8 of hearts',\n",
      " '7 of hearts',\n",
      " '7 of spades',\n",
      " 'Jack of clubs',\n",
      " '8 of spades']\n"
     ]
    }
   ],
   "source": [
    "#假设你要编写一个程序，在用户每次按回车键时都发给他一张牌。另外， 你还要确保发给用户的每张牌都不同。\n",
    "from pprint import pprint\n",
    "from random import *\n",
    "values = list(range(1, 11)) + 'Jack Queen King'.split()\n",
    "suits = 'diamonds clubs hearts spades'.split()\n",
    "deck = ['{} of {}'.format(v, s) for v in values for s in suits]\n",
    "shuffle(deck)\n",
    "pprint(deck[:12])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "shelve 和 json\n",
    "```\n",
    "要正确地修改使用模块shelve存储的对象，必须将获取的副本赋给一个临时变量，并在修改这个副本后再次存储```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "re 正则表达式\n",
    "```\n",
    "compile(pattern[, flags]) 根据包含正则表达式的字符串创建模式对象\n",
    "search(pattern, string[, flags]) 在字符串中查找模式\n",
    "match(pattern, string[, flags]) 在字符串开头匹配模式\n",
    "split(pattern, string[, maxsplit=0]) 根据模式来分割字符串\n",
    "findall(pattern, string) 返回一个列表，其中包含字符串中所有与模式匹配的子串\n",
    "sub(pat, repl, string[, count=0]) 将字符串中与模式pat匹配的子串都替换为repl\n",
    "escape(string) 对字符串中所有的正则表达式特殊字符都进行转义\n",
    "\n",
    "group([group1, ...]) 获取与给定子模式（编组）匹配的子串\n",
    "start([group]) 返回与给定编组匹配的子串的起始位置\n",
    "end([group]) 返回与给定编组匹配的子串的终止位置（与切片一样，不包含终止位置）\n",
    "span([group]) 返回与给定编组匹配的子串的起始和终止位置\n",
    "\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第11章 文件\n",
    "\n",
    "- ```\n",
    "模式：\n",
    "'r' 读取模式（默认值）\n",
    "'w' 写入模式\n",
    "'x' 独占写入模式\n",
    "'a' 附加模式\n",
    "'b' 二进制模式（与其他模式结合使用）\n",
    "'t' 文本模式（默认值，与其他模式结合使用）\n",
    "'+' 读写模式（与其他模式结合使用）\n",
    "```\n",
    "\n",
    "- 使用管道重定向输出  在bash等shell中，可依次输入多个命令，并使用管道将它们链接起来，如下所示：\n",
    "$ cat somefile.txt | python somescript.py | sort\n",
    "\n",
    "- open , read ,readline,readlines"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "with open(filename) as f:\n",
    "    while True:\n",
    "        line = f.readline()\n",
    "        if not line: break\n",
    "        process(line)\n",
    "        \n",
    "  ```  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###  第12章 图形用户界面"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from tkinter import *\n",
    "top = Tk()\n",
    "mainloop()\n",
    "from tkinter import *\n",
    "btn = Button()\n",
    "btn.pack()\n",
    "btn['text'] = 'click me!'\n",
    "\n",
    "\n",
    "def clicked():\n",
    "    print('I was clicked!')\n",
    "\n",
    "btn['command'] = clicked\n",
    "btn.config(text='Click me!', command=clicked)\n",
    "# Button(text='Click me too!', command=clicked).pack()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "''"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from tkinter import *\n",
    "from tkinter.scrolledtext import ScrolledText\n",
    "\n",
    "def load():\n",
    "    with open(filename.get()) as file:\n",
    "        contents.delete('1.0', END)\n",
    "        contents.insert(INSERT, file.read())\n",
    "def save():\n",
    "    with open(filename.get(), 'w') as file:\n",
    "        file.write(contents.get('1.0', END))\n",
    "\n",
    "top = Tk()\n",
    "top.title(\"Simple Editor\")\n",
    "\n",
    "contents = ScrolledText()\n",
    "contents.pack(side=BOTTOM, expand=True, fill=BOTH)\n",
    "\n",
    "filename = Entry()\n",
    "filename.pack(side=LEFT, expand=True, fill=X)\n",
    "\n",
    "Button(text='Open', command=load).pack(side=LEFT)\n",
    "Button(text='Save', command=save).pack(side=LEFT)\n",
    "\n",
    "mainloop()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第13章 数据库支持"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python DB API的模块属性\n",
    "```\n",
    "apilevel 使用的Python DB API版本\n",
    "threadsafety 模块的线程安全程度如何\n",
    "paramstyle 在SQL查询中使用哪种参数风格\n",
    "```\n",
    "Python DB API指定的异常\n",
    "```\n",
    "StandardError 所有异常的超类\n",
    "Warning StandardError 发生非致命问题时引发\n",
    "Error StandardError 所有错误条件的超类\n",
    "InterfaceError Error 与接口（而不是数据库）相关的错误\n",
    "DatabaseError Error 与数据库相关的错误的超类\n",
    "DataError DatabaseError 与数据相关的问题，如值不在合法的范围内\n",
    "OperationalError DatabaseError 数据库操作内部的错误\n",
    "IntegrityError DatabaseError 关系完整性遭到破坏，如键未通过检查\n",
    "InternalError DatabaseError 数据库内部的错误，如游标无效\n",
    "ProgrammingError DatabaseError 用户编程错误，如未找到数据库表\n",
    "NotSupportedError DatabaseError 请求不支持的功能，如回滚\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第14章 网络编程\n",
    "\n",
    " 几个网络模块\n",
    "- 模块 socket\n",
    "- 模块 urllib 和 urllib2\n",
    "- 其他模块\n",
    "> ```\n",
    "asynchat 包含补充asyncore的功能（参见第24章）\n",
    "asyncore 异步套接字处理程序（参见第24章）\n",
    "cgi 基本的CGI支持（参见第15章）\n",
    "Cookie Cookie对象操作，主要用于服务器\n",
    "cookielib 客户端Cookie支持\n",
    "email 电子邮件（包括MIME）支持\n",
    "ftplib FTP客户端模块\n",
    "gopherlib Gopher客户端模块\n",
    "httplib HTTP 客户端模块\n",
    "imaplib IMAP4客户端模块\n",
    "mailbox 读取多种邮箱格式\n",
    "mailcap 通过mailcap文件访问MIME配置\n",
    "mhlib 访问MH邮箱\n",
    "nntplib NNTP客户端模块（参见第23章）\n",
    "poplib POP客户端模块\n",
    "robotparser 解析Web服务器robot文件\n",
    "SimpleXMLRPCServer 一个简单的XML-RPC服务器（参见第27章）\n",
    "smtpd SMTP服务器模块\n",
    "smtplib SMTP客户端模块\n",
    "telnetlib Telnet客户端模块\n",
    "urlparse 用于解读URL\n",
    "xmlrpclib XML-RPC客户端支持（参见第27章）\n",
    "```\n",
    "- SocketServer 及相关的类\n",
    "- 多个连接\n",
    ">- 使用 SocketServer 实现分叉和线程化\n",
    ">- 使用 select 和 poll 实现异步 I/O\n",
    "- Twisted :事件驱动的Python网络框架"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import socket\n",
    "s = socket.socket()\n",
    "host = socket.gethostname()\n",
    "port = 1234\n",
    "s.bind((host, port))\n",
    "\n",
    "s.listen(5)\n",
    "while True:\n",
    "    c, addr = s.accept()\n",
    "    print('Got connection from', addr)\n",
    "    c.send('Thank you for connecting')\n",
    "    c.close()\n",
    "    break;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import socket\n",
    "s = socket.socket()\n",
    "host = socket.gethostname()\n",
    "port = 1234\n",
    "s.connect((host, port))\n",
    "print(s.recv(1024))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第15章 Python和Web\n",
    "- 屏幕抓取\n",
    "\n",
    "Tidy 和 XHTML 解析\n",
    "\n",
    "- CGI \n",
    "- mod_python\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from urllib.request import urlopen\n",
    "import re\n",
    "p = re.compile('<a href=\"(/jobs/\\\\d+)/\">(.*?)</a>')\n",
    "text = urlopen('http://python.org/jobs').read().decode()\n",
    "for url, name in p.findall(text):\n",
    "    print('{} ({})'.format(name, url))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第16章 测试基础\n",
    "\n",
    "\n",
    "- 测试驱动编程\n",
    "- 测试工具 doctest 与 unittest\n",
    "```\n",
    "doctest.testmod(module) 检查文档字符串中的示例（还接受很多其他的参数）\n",
    "unittest.main() 运行当前模块中的单元测试\n",
    "profile.run(stmt[,filename]) 执行语句并对其进行性能分析；可将分析结果保存到参数filename指定的文件中\n",
    "```\n",
    "- 使用 PyChecker 和 PyLint 检查源代码\n",
    "- 性能分析"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第17章 扩展Python\n",
    "\n",
    "- 优化方法\n",
    "```\n",
    "(1) 使用Python开发原型（有关原型开发的详细信息，请参阅第19章） 。\n",
    " (2) 对程序进行性能分析以找出瓶颈（有关测试，请参阅第16章）。\n",
    " (3) 使用C（或者C++、 C#、 Java、 Fortran等）扩展重写瓶颈部分。\n",
    "```\n",
    "- 简单易行的方式：<br/>\n",
    "Jython 和 IronPython  :可轻松地使用原生\n",
    "模块来扩展Python，因为Jython和IronPython能够让你访问底层语言中的模块和类 （对Jython来说，底层语言为Java；对IronPython来说，为C#和其他.NET语言），从而无需像扩展CPython那样遵循.<br/><br/>\n",
    "编写 C 语言扩展 <br/>\n",
    "SWIG 指的是简单包装器和接口生成器（simple wrapper and interface\n",
    "generator），是一个适用于多种语言的工具。<br/><br/>\n",
    "特定的API。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第18章 程序打包\n",
    "- Setuptools 基础\n",
    "- 打包\n",
    "- 编译扩展\n",
    "- 使用py2exe创建可执行程序\n",
    "\n",
    "Setuptools的命令：可使用多个命令来运行setup.py脚本，如build、 build_ext、 install、\n",
    "sdist和bdist。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第19章 趣味编程 \n",
    "编程柔术 ：注重灵活\n",
    "的反应，宁弯勿折：不力图用计划好的动作打击对手，而是顺势而为，借力打力。这样（从理论\n",
    "上说）能打败比你更高大、更狡猾、更强壮的对手。\n",
    "\n",
    "- 原型设计。快速编写\n",
    "- 配置。旨在让程序的某些方面修改起来更容易。from configparser import ConfigParser\n",
    "- 日志 import logging"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第20章 项目1：自动添加标签\n",
    "yield\n",
    "- 解析器：添加一个读取文本并管理其他类的对象。\n",
    "- 规则：对于每种文本块，都制定一条相应的规则。这些规则能够检测不同类型的文本块\n",
    "并相应地设置其格式。\n",
    "- 过滤器：使用正则表达式来处理内嵌元素。\n",
    "- 处理程序：供解析器用来生成输出。每个处理程序都生成不同的标记。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第21章  项目2：绘制图表\n",
    "\n",
    "PDF （portable document format）\n",
    "这样的包有很多，我选择的是ReportLab，因为它易于使用，并且提供了丰富的PDF图形和文档生成功能。如果你不想只是蜻蜓点水，可考\n",
    "虑使用图形包PYX （http://pyx.sf.net )，其功能非常强大，并支持基于TEX排版。<br/>\n",
    "要获取ReportLab包，可访问其官网http://www.reportlab.org ，其中包含软件、文档和示例。\n",
    "你可从这个网站下载ReportLab，也可使用pip来安装它(pip install reportlab)。<br/>\n",
    "ftp://ftp.swpc.noaa.gov/pub/weekly/Predict.txt 下载太阳黑子等数据"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第22章  项目3:万能的XML\n",
    "Simple API for XML（SAX）来处理XML文件。\n",
    "\n",
    "from xml.sax import make_parser"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第23章 新闻汇总\n",
    "\n",
    "nntplib\n",
    "https://docs.python.org/library/nntplib.html\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第24章 项目5：虚拟茶话会\n",
    "\n",
    "框架Twisted，其核心是LineReceiver类。在本章中，我将只使用标准库中的异步网络\n",
    "编程模块。<br/>\n",
    "有关模块asyncore和asynchat的文档\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第25章 使用CGI进行远程编辑\n",
    "编写CGI程序时，使用的主要工具包括模块cgi以及用于调试的模块cgitb。\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第26章 自建公告板\n",
    "CGI工具外，还需要一个SQL数据库，<br/>\n",
    "单机数据库SQLite，也可使用其他系统，如下面这两种优秀的免费数据库：\n",
    " PostgreSQL（http://www.postgresql.org）\n",
    " MySQL（http://www.mysql.org)\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第27章 使用XML-RPC共享文件\n",
    "使用的主要模块为xmlrpc.client和xmlrpc.server。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第28章 使用GUI共享文件\n",
    "除第27章使用的工具外，还需要使用大部分Python版本都自带的工具包Tkinter。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第29章 自制街机游戏\n",
    "使用Pygame"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
